package semantico;

import lexico.Token;
import simbolos.Tipo;

/**
 * Implementa suporte para expressoes logicas, como '&&', '||', '<', '>', etc.
 * @author Cefanys
 */
public class OperadorLogico extends Expressao{

	public Expressao expressao1;
	public Expressao expressao2;
	
	public OperadorLogico(Token token, Expressao expressao1, Expressao expressao2) throws SemanticoException{
		super(token, null); //inicialmente nao ha um tipo definido (null)
		this.expressao1 = expressao1;
		this.expressao2 = expressao2;
		tipo = tipoExpressao(expressao1.tipo, expressao2.tipo);
		
		if(tipo == null) montaErro(1, "");
	}
	
	public Tipo tipoExpressao(Tipo op1, Tipo op2){
		if(op1.equals(Tipo.LOGICO) && op2.equals(Tipo.LOGICO)){
			return Tipo.LOGICO;
		}else{
			return null;
		}
	}
	
	/**
	 * Retorna um temporario cujo valor e' determinado pelo fluxo de controle
	 * pelo codigo de desvio para essa expressao. Na saida verdadeira e'
	 * atribuido o valor true ao temporario e na saida falsa e' atribuido o valor
	 * false ao temporario
	 * @throws SemanticoException 
	 */
	public Expressao gerarTermo() throws SemanticoException{
		int saidaFalsa = novoRotulo();
		int a = novoRotulo();
		Temporario temp = new Temporario(tipo);
		this.desviar(0, saidaFalsa);
		emitirCodigo(temp.toString() + " = true");
		emitirCodigo("goto L" + a);
		emitirRotulos(saidaFalsa);
		emitirCodigo(temp.toString() + " = false");
		emitirRotulos(a);
		return temp;
	}
	
	public String toString(){
		return expressao1.toString() + " " + operador.toString() + " " + expressao2.toString();
	}
}
